﻿using System.Collections.Concurrent;
using Microsoft.AspNetCore.SignalR;
using ChatServer.Models;

namespace ChatServer.Servers
{
    public class ChatHub : Hub<IClient>
    {
        private static readonly ConcurrentDictionary<string, User> ChatClientDict = new(); //用户字典

        //建立连接回调
        public override Task OnConnectedAsync()
        {
            var userName = ChatClientDict.SingleOrDefault((c) => c.Value.Id == Context.ConnectionId).Key;
            if (!string.IsNullOrWhiteSpace(userName))
            {
                Clients.Others.ParticipantConnected(userName);
            }

            Console.WriteLine($"{Context.ConnectionId} 已连接");
            return base.OnConnectedAsync();
        }

        //断开连接回调
        public override Task OnDisconnectedAsync(Exception? exception)
        {
            var userName = ChatClientDict.SingleOrDefault((c) => c.Value.Id == Context.ConnectionId).Key;
            if (!string.IsNullOrWhiteSpace(userName))
            {
                ChatClientDict.Remove(userName, out _);
                Clients.Others.ParticipantDisconnected(userName);
            }

            Console.WriteLine($"{Context.ConnectionId} 已断开: {exception?.Message}");
            return base.OnDisconnectedAsync(exception);
        }


        //登录功能
        public async Task<Tuple<bool, List<User>>> Login(string userId, byte[] photo)
        {
            var userList = new List<User>();
            if (string.IsNullOrWhiteSpace(userId))
            {
                return new Tuple<bool, List<User>>(false, userList);
            }

            Console.WriteLine($"{Context.ConnectionId} 登录");

            if (!ChatClientDict.ContainsKey(userId))
            {
                userList.AddRange(ChatClientDict.Values);

                var newUser = new User { Name = userId, Id = Context.ConnectionId, Photo = photo };
                var added = ChatClientDict.TryAdd(userId, newUser);
                if (!added)
                {
                    userList.Clear();
                    return new Tuple<bool, List<User>>(false, userList);
                }

                await Clients.Others.ParticipantLogin(newUser);
            }
            else
            {
                var user = ChatClientDict[userId];
                user.Photo = photo;

                userList.AddRange(ChatClientDict.Values.Where(t => t.Id != userId));
            }

            return new Tuple<bool, List<User>>(true, userList);
        }

        //退出
        public async Task Logout(string userId)
        {
            if (string.IsNullOrWhiteSpace(userId))
            {
                return;
            }

            Console.WriteLine($"{userId} 退出");

            ChatClientDict.TryRemove(userId, out _);
            await Clients.Others.ParticipantLogout(userId);
        }

        //广播文本消息
        public async Task BroadcastTextMessage(string userId, string message)
        {
            if (!string.IsNullOrWhiteSpace(userId) && !string.IsNullOrWhiteSpace(message))
            {
                await Clients.Others.BroadcastTextMessage(userId, message);
            }
        }

        //广播图像消息
        public async Task BroadcastImageMessage(string userId, byte[] image)
        {
            if (!string.IsNullOrWhiteSpace(userId) && image.Length > 0)
            {
                await Clients.Others.BroadcastImageMessage(userId, image);
            }
        }

        //单播文本消息
        public async Task UniCastTextMessage(string sender, string recipient, string message)
        {
            if (string.IsNullOrWhiteSpace(sender) ||
                string.IsNullOrWhiteSpace(message) ||
                recipient == sender ||
                !ChatClientDict.ContainsKey(recipient) ||
                !ChatClientDict.TryGetValue(recipient, out var client) ||
                string.IsNullOrWhiteSpace(client.Id))
            {
                return;
            }

            await Clients.Client(client.Id).UniCastTextMessage(sender, message);
        }

        //单播图像消息
        public async Task UniCastImageMessage(string sender, string recipient, byte[] image)
        {
            if (string.IsNullOrWhiteSpace(sender) ||
                image.Length == 0 ||
                recipient == sender ||
                !ChatClientDict.ContainsKey(recipient) ||
                !ChatClientDict.TryGetValue(recipient, out var client) ||
                string.IsNullOrWhiteSpace(client.Id))
            {
                return;
            }

            await Clients.Client(client.Id).UniCastImageMessage(sender, image);
        }

        //正在输入
        public async Task Typing(string sender, string recipient)
        {
            if (string.IsNullOrWhiteSpace(sender) ||
                string.IsNullOrWhiteSpace(recipient) ||
                sender == recipient ||
                !ChatClientDict.ContainsKey(recipient) ||
                !ChatClientDict.TryGetValue(recipient, out var client) ||
                string.IsNullOrWhiteSpace(client.Id))
            {
                return;
            }

            await Clients.Client(client.Id).ParticipantTyping(sender);
        }
    }
}
